<template>
  <div class="goods-sku">
    <div class="item" v-for="attr in attrs" :key="attr.name">
      <div class="dt">{{ attr.name }}</div>
      <div class="dd">
        <template v-for="item in attr.values">
          <img
            :class="{
              disabled: item.disabled,
              selected: item.selected
            }"
            @click="clickAttr(attr, item)"
            :key="item.name"
            v-if="item.picture"
            :src="item.picture"
            :alt="item.name"
            :title="item.name"
          />
          <span
            :class="{
              disabled: item.disabled,
              selected: item.selected
            }"
            @click="clickAttr(attr, item)"
            :key="item.name"
            v-else
            class="size"
            >{{ item.name }}</span
          >
        </template>
      </div>
    </div>
  </div>
</template>

<script>
import powerSet from '@/vender/power-set'
export default {
  name: 'goods-sku',
  props: {
    attrs: {
      type: Array,
      default: () => []
    },
    sku: {
      type: Array,
      default: () => []
    },
    currentSkuId: {
      type: [String, Number],
      default: ''
    }
  },
  data () {
    return {
      skuPathMap: {},
      activeAttrs: {},
      spliter: '※'
    }
  },
  computed: {
    selected () {
      return Object.keys(this.activeAttrs).map(key => this.activeAttrs[key])
    }
  },
  created () {
    // 为attrs添加控制选中和禁用的响应式数据
    // 如果有默认的sku需要去修改状态
    const currSku = this.sku.find(item => item.id === this.currentSkuId)
    this.attrs.forEach((attr, i) => {
      attr.values.forEach(item => {
        this.$set(item, 'disabled', false)
        this.$set(item, 'selected', false)
        if (currSku && currSku.specs[i].name === attr.name && currSku.specs[i].valueName === item.name) {
          this.$set(item, 'selected', true)
        }
      })
    })
    // 根据sku生成所有存在子集组合（路径）映射对象
    this.skuPathMap = this.getPathMapBySku()
    // 更新属性按钮状态
    this.updateItemStatus()
  },
  methods: {
    // 根据sku生成所有存在子集组合（路径）映射对象
    getPathMapBySku () {
      const pathMap = {}
      this.sku.forEach(item => {
        if (item.inventory > 0) {
          // 单条sku的属性值数组：[a,b,c]
          const skuAttrValues = item.specs.map(item => item.valueName)
          // 单条sku的属性值数组子集：[[],[a],[b],[a,b],[c],[a,c],[b,c],[a,b,c]]
          const skuAttrSubSet = powerSet(skuAttrValues)
          // 遍历子集，汇总到pathMap
          skuAttrSubSet.forEach(subSet => {
            // a,b,c ===> a※b※c 或者 a,b ===> a※b
            const key = subSet.join(this.spliter)
            // 相同key记录多条sku，完整的key只会记录唯一sku
            if (pathMap[key]) {
              pathMap[key].push(item.id)
            } else {
              pathMap[key] = [item.id]
            }
          })
        }
      })
      return pathMap
    },
    clickAttr (attr, item) {
      // 禁用的不做任何操作
      if (item.disabled) return
      // 按钮选中与取消选中
      item.selected = !item.selected
      attr.values.forEach(it => {
        if (it.name !== item.name) it.selected = false
      })
      // 更新按钮的禁用状态
      this.updateItemStatus()
      // 如果选择，触发on-change事件，完成sku就提交数据，否则提交空对象
      const skuIds = this.skuPathMap[this.getSelectedValues().join(this.spliter)]
      if (skuIds && skuIds[0]) {
        const { id: skuId, price, oldPrice, inventory: stock, specs: attrs } = this.sku.find(item => item.id === skuIds[0])
        this.$emit('on-change', {
          skuId,
          price,
          oldPrice,
          stock,
          attrsText: attrs.reduce((prev, next) => `${prev} ${next.name}：${next.valueName}`, '').replace(' ', '')
        })
      } else {
        this.$emit('on-change', {})
      }
    },
    // 更新属性按钮状态
    updateItemStatus () {
      this.attrs.forEach((attr, i) => {
        const selectedValues = this.getSelectedValues()
        attr.values.forEach(item => {
          if (selectedValues[i] === item.name) return
          selectedValues[i] = item.name
          const mapKey = selectedValues.filter(item => item).join(this.spliter)
          console.log(mapKey)
          item.disabled = !this.skuPathMap[mapKey]
        })
      })
    },
    // 拿到当前选中属性值数组
    getSelectedValues () {
      const selectedValues = []
      this.attrs.forEach((attr, i) => {
        const selectedValue = attr.values.find(item => item.selected === true)
        selectedValues[i] = selectedValue ? selectedValue.name : undefined
      })
      return selectedValues
    }
  }
}
</script>

<style scoped lang='less'>
.goods-sku {
  padding: 0 10px;
  .item {
    color: #999;
    display: flex;
    padding-top: 20px;
    align-items: center;
    .dt {
      width: 50px;
    }
    .dd {
      flex: 1;
      color: #666;
    }
  }
  img {
    width: 50px;
    height: 50px;
    margin-right: 10px;
    border: 1px solid #e4e4e4;
    cursor: pointer;
    &.selected {
      border-color: @xtxColor;
    }
    &.disabled {
      border: 1px dashed #ccc;
      cursor: not-allowed;
      opacity: 0.5;
    }
  }
  .size {
    border: 1px solid #e4e4e4;
    padding: 5px 25px;
    display: inline-block;
    margin-right: 10px;
    line-height: 20px;
    cursor: pointer;
    user-select: none;
    &.selected {
      border-color: @xtxColor;
      color: @xtxColor;
    }
    &.disabled {
      border: 1px dashed #ccc;
      cursor: not-allowed;
      opacity: 0.4;
    }
  }
}
</style>
